﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using ColumnModuleAndEdit.ColumnModule.DataDefine;
using YArchitech.Revit.RevitExtension;
using YJKArchMethodLibrary.Utils;

namespace ColumnModuleAndEdit.ColumnModule
{
	public abstract class ColumnFamilyCreator
	{
        public ColumnFamilyCreator(ExternalCommandData cmdData, ColumnFamily familyInfos, ElementId materialId, Autodesk.Revit.DB.Document familyDocument)
		{
			this.m_Revit = cmdData;
			this.m_RevitApp = this.m_Revit.Application.Application;
			this.m_FamilyDocument = familyDocument;
			this.m_FamilyInfos = familyInfos;
			this.m_MaterialId = materialId;
			this.m_FamilyItemFactory = this.m_FamilyDocument.FamilyCreate;
			this.GetDocumentTemplateInfos();
		}

		public abstract Result AddReferencePlanes(ref string message);

		public abstract Result CreateExtrusion(ref string message);

		public abstract Result AddAlignments(ref string message);

		public abstract Result AddParameters(ref string message);

		public abstract Result AddDimensions(ref string message);

		public abstract Result AddSymbols(ref string message);

		protected Result GetDocumentTemplateInfos()
		{
            List<Autodesk.Revit.DB.View> elements = Utility.GetElements<Autodesk.Revit.DB.View>(this.m_FamilyDocument);
            foreach (Autodesk.Revit.DB.View view in elements)
			{
				if (view.Name.CompareTo("前") == 0 || view.Name.CompareTo("Front") == 0)
				{
					this.m_FrontView = view;
				}
				else if (view.Name.CompareTo("右") == 0 || view.Name.CompareTo("Right") == 0)
				{
					this.m_RightView = view;
				}
                else if ((view.Name.CompareTo("低于参照标高") == 0 || view.Name.CompareTo("Lower Ref. Level") == 0) && (int)view.ViewType == 1)
				{
					this.m_LowerLevelView = view;
				}
			}
			List<Level> elements2 = Utility.GetElements<Level>(this.m_FamilyDocument);
			foreach (Level level in elements2)
			{
				if (level.Name.CompareTo("低于参照标高") == 0 || level.Name.CompareTo("Lower Ref. Level") == 0)
				{
					this.m_LowerLevel = level;
				}
				else if (level.Name.CompareTo("高于参照标高") == 0 || level.Name.CompareTo("Upper Ref Level") == 0)
				{
					this.m_UpperLevel = level;
				}
			}
			List<ReferencePlane> elements3 = Utility.GetElements<ReferencePlane>(this.m_FamilyDocument);
			foreach (ReferencePlane referencePlane in elements3)
			{
				if (referencePlane.Name.CompareTo("参照平面") == 0 || referencePlane.Name.CompareTo("Reference Plane") == 0)
				{
					this.m_BottomRefPlane = referencePlane;
				}
				else if (referencePlane.Name.CompareTo("中心(前/后)") == 0 || referencePlane.Name.CompareTo("Center (Front/Back)") == 0)
				{
					this.m_MiddleFBRefPlane = referencePlane;
				}
				else if (referencePlane.Name.CompareTo("中心(左/右)") == 0 || referencePlane.Name.CompareTo("Center (Left/Right)") == 0)
				{
					this.m_MiddleLRFefPlace = referencePlane;
				}
				else if (referencePlane.Name.CompareTo("左") == 0 || referencePlane.Name.CompareTo("Left") == 0)
				{
					this.m_LeftRefPlane = referencePlane;
				}
				else if (referencePlane.Name.CompareTo("右") == 0 || referencePlane.Name.CompareTo("Right") == 0)
				{
					this.m_RightRefPlace = referencePlane;
				}
				else if (referencePlane.Name.CompareTo("前") == 0 || referencePlane.Name.CompareTo("Front") == 0)
				{
					this.m_FrontRefPlane = referencePlane;
				}
				else if (referencePlane.Name.CompareTo("后面") == 0 || referencePlane.Name.CompareTo("Back") == 0)
				{
					this.m_BackRefPlane = referencePlane;
				}
			}
			this.m_Depth = this.m_FamilyDocument.FamilyManager.get_Parameter("深度");
			if (this.m_Depth == null)
			{
				this.m_Depth = this.m_FamilyDocument.FamilyManager.get_Parameter("Depth");
			}
			this.m_Width = this.m_FamilyDocument.FamilyManager.get_Parameter("宽度");
			if (this.m_Width == null)
			{
				this.m_Depth = this.m_FamilyDocument.FamilyManager.get_Parameter("Width");
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		protected virtual List<CurveArrArray> CreateProfileShape()
		{
			return this.m_FamilyInfos.GetCurvesByEdgeLoops(this.m_RevitApp);
		}

		protected Face GetExtrusionPlaneFace(Extrusion extrusion, View view, XYZ planeFaceNormal, ReferencePlane refPlane)
		{
			return this.GetExtrusionPlaneFace(extrusion, view, planeFaceNormal);
		}

		protected Face GetExtrusionPlaneFace(Extrusion extrusion, View view, XYZ planeFaceNormal)
		{
			Face result = null;
			FaceArray faceArray = null;
			if (extrusion.IsSolid)
			{
				List<GeometryObject> geometryObjectArray = RevitVersionFuncs.GetGeometryObjectArray(extrusion.get_Geometry(new Options
				{
					ComputeReferences = true,
					View = view
				}));
				foreach (GeometryObject geometryObject in geometryObjectArray)
				{
					if (geometryObject is Solid)
					{
						Solid solid = geometryObject as Solid;
						faceArray = solid.Faces;
					}
				}
				foreach (object obj in faceArray)
				{
					Face face = (Face)obj;
					if (!(face.GetType() != typeof(PlanarFace)))
					{
						XYZ xyz = Utility.GetNormalWithFace(face) - planeFaceNormal;
						if (Geometry.IsEqual(xyz.GetLength(), 0.0))
						{
							result = face;
							break;
						}
					}
				}
			}
			return result;
		}

		protected Dimension AddDimension(View view, Face face1, Face face2)
		{
			ReferenceArray referenceArray = new ReferenceArray();
			PlanarFace planarFace = face1 as PlanarFace;
			Reference reference = planarFace.Reference;
			PlanarFace planarFace2 = face2 as PlanarFace;
			Reference reference2 = planarFace2.Reference;
			if (reference != null && reference2 != null)
			{
				referenceArray.Append(reference);
				referenceArray.Append(reference2);
			}
			XYZ xyz = new XYZ(planarFace.Origin.X, planarFace.Origin.Z, planarFace.Origin.Y);
			XYZ endPoint = new XYZ(xyz.X, planarFace2.Origin.Z, xyz.Z);
			SubTransaction subTransaction = new SubTransaction(this.m_FamilyDocument);
			subTransaction.Start();
			Line line = YJKLineEx.YJKGetBound(xyz, endPoint);
			Dimension result = this.m_FamilyDocument.FamilyCreate.NewDimension(view, line, referenceArray);
			subTransaction.Commit();
			return result;
		}

		protected ExternalCommandData m_Revit;

        protected Autodesk.Revit.DB.Document m_FamilyDocument;

		protected ColumnFamily m_FamilyInfos;

		protected ElementId m_MaterialId;

        protected Autodesk.Revit.ApplicationServices.Application m_RevitApp;

		protected FamilyItemFactory m_FamilyItemFactory;

		protected List<Extrusion> m_ExtrusionList = new List<Extrusion>();

		protected View m_FrontView;

		protected View m_RightView;

		protected View m_LowerLevelView;

		protected Level m_LowerLevel;

		protected Level m_UpperLevel;

		protected ReferencePlane m_MiddleFBRefPlane;

		protected ReferencePlane m_MiddleLRFefPlace;

		protected ReferencePlane m_LeftRefPlane;

		protected ReferencePlane m_RightRefPlace;

		protected ReferencePlane m_FrontRefPlane;

		protected ReferencePlane m_BackRefPlane;

		protected ReferencePlane m_BottomRefPlane;

		protected FamilyParameter m_Depth;

		protected FamilyParameter m_Width;
	}
}
